home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / shell / dialog-0.000 / dialog-0 / dialog-0.6c / old / radiolist.c < prev   
Encoding:
C/C++ Source or Header  |  1995-08-17  |  10.4 KB  |  350 lines

  1. /*
  2.  *  radiolist.c -- implements the radiolist box
  3.  *
  4.  *  AUTHOR: Stuart Herbert - S.Herbert@sheffield.ac.uk
  5.  *   (from checklist.c by Savio Lam (lam836@cs.cuhk.hk))
  6.  *
  7.  *  This program is free software; you can redistribute it and/or
  8.  *  modify it under the terms of the GNU General Public License
  9.  *  as published by the Free Software Foundation; either version 2
  10.  *  of the License, or (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. #include "dialog.h"
  23.  
  24. static int list_width, check_x, item_x;
  25.  
  26. /*
  27.  * Print list item
  28.  */
  29. static void
  30. print_item (WINDOW * win, const char *tag, const char *item, int status,
  31.         int choice, int selected)
  32. {
  33.     int i;
  34.  
  35.     /* Clear 'residue' of last item */
  36.     wattrset (win, menubox_attr);
  37.     wmove (win, choice, 0);
  38.     for (i = 0; i < list_width; i++)
  39.     waddch (win, ' ');
  40.     wmove (win, choice, check_x);
  41.     wattrset (win, selected ? check_selected_attr : check_attr);
  42.     wprintw (win, "(%c)", status ? '*' : ' ');
  43.     wattrset (win, menubox_attr);
  44.     waddch (win, ' ');
  45.     wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
  46.     waddch (win, tag[0]);
  47.     wattrset (win, selected ? tag_selected_attr : tag_attr);
  48.     waddstr (win, tag + 1);
  49.     wmove (win, choice, item_x);
  50.     wattrset (win, selected ? item_selected_attr : item_attr);
  51.     waddstr (win, item);
  52. }
  53.  
  54. /*
  55.  * Display a dialog box with a list of options that can be turned on or off
  56.  */
  57. int
  58. dialog_radiolist (char *title, char *prompt, int height, int width,
  59.           int list_height, int item_no, const char * const * items)
  60. {
  61.     int i, x, y, cur_x, cur_y, box_x, box_y, key = 0;
  62.     int button = 0, choice = 0, scroll = 0, max_choice, *status;
  63.     WINDOW *dialog, *list;
  64.  
  65.     /* Allocate space for storing item on/off status */
  66.     if ((status = malloc (sizeof (int) * item_no)) == NULL) {
  67.     endwin ();
  68.     fprintf (stderr,
  69.          "\nCan't allocate memory in dialog_radiolist().\n");
  70.     exit (-1);
  71.     }
  72.     /* Initializes status */
  73.     for (i = 0; i < item_no; i++)
  74.     status[i] = !strcasecmp (items[i * 3 + 2], "on");
  75.  
  76.     max_choice = MIN (list_height, item_no);
  77.  
  78.     /* center dialog box on screen */
  79.     x = (COLS - width) / 2;
  80.     y = (LINES - height) / 2;
  81.  
  82. #ifdef HAVE_NCURSES
  83.     if (use_shadow)
  84.     draw_shadow (stdscr, y, x, height, width);
  85. #endif
  86.     dialog = newwin (height, width, y, x);
  87.     keypad (dialog, TRUE);
  88.  
  89.     draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
  90.     wattrset (dialog, border_attr);
  91.     wmove (dialog, height - 3, 0);
  92.     waddch (dialog, ACS_LTEE);
  93.     for (i = 0; i < width - 2; i++)
  94.     waddch (dialog, ACS_HLINE);
  95.     wattrset (dialog, dialog_attr);
  96.     waddch (dialog, ACS_RTEE);
  97.     wmove (dialog, height - 2, 1);
  98.     for (i = 0; i < width - 2; i++)
  99.     waddch (dialog, ' ');
  100.  
  101.     if (title != NULL) {
  102.     wattrset (dialog, title_attr);
  103.     wmove (dialog, 0, (width - strlen (title)) / 2 - 1);
  104.     waddch (dialog, ' ');
  105.     waddstr (dialog, title);
  106.     waddch (dialog, ' ');
  107.     }
  108.     wattrset (dialog, dialog_attr);
  109.     print_autowrap (dialog, prompt, width - 2, 1, 3);
  110.  
  111.     list_width = width - 6;
  112.     getyx (dialog, cur_y, cur_x);
  113.     box_y = cur_y + 1;
  114.     box_x = (width - list_width) / 2 - 1;
  115.  
  116.     /* create new window for the list */
  117.     list = subwin (dialog, list_height, list_width, y + box_y + 1,
  118.            x + box_x + 1);
  119.     keypad (list, TRUE);
  120.  
  121.     /* draw a box around the list items */
  122.     draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
  123.           menubox_border_attr, menubox_attr);
  124.  
  125.     check_x = 0;
  126.     item_x = 0;
  127.     /* Find length of longest item in order to center radiolist */
  128.     for (i = 0; i < item_no; i++) {
  129.     check_x = MAX (check_x, strlen (items[i * 3])
  130.                + strlen (items[i * 3 + 1]) + 6);
  131.     item_x = MAX (item_x, strlen (items[i * 3]));
  132.     }
  133.     check_x = (list_width - check_x) / 2;
  134.     item_x = check_x + item_x + 6;
  135.  
  136.     /* Print the list */
  137.     for (i = 0; i < max_choice; i++)
  138.     print_item (list, items[i * 3], items[i * 3 + 1],
  139.             status[i], i, i == choice);
  140.     wnoutrefresh (list);
  141.  
  142.     if (list_height < item_no) {
  143.     wattrset (dialog, darrow_attr);
  144.     wmove (dialog, box_y + list_height + 1, box_x + check_x + 5);
  145.     waddch (dialog, ACS_DARROW);
  146.     wmove (dialog, box_y + list_height + 1, box_x + check_x + 6);
  147.     waddstr (dialog, "(+)");
  148.     }
  149.     x = width / 2 - 11;
  150.     y = height - 2;
  151.     print_button (dialog, "Cancel", y, x + 14, FALSE);
  152.     print_button (dialog, "  OK  ", y, x, TRUE);
  153.     wrefresh (dialog);
  154.  
  155.     while (key != ESC) {
  156.     key = wgetch (dialog);
  157.     for (i = 0; i < max_choice; i++)
  158.         if (toupper (key) == toupper (items[(scroll + i) * 3][0]))
  159.         break;
  160.  
  161.     if (i < max_choice ||
  162.         (key >= '1' && key <= MIN ('9', '0' + max_choice)) ||
  163.         key == KEY_UP || key == KEY_DOWN || key == ' ' ||
  164.         key == '+' || key == '-') {
  165.         if (key >= '1' && key <= MIN ('9', '0' + max_choice))
  166.         i = key - '1';
  167.         else if (key == KEY_UP || key == '-') {
  168.         if (!choice) {
  169.             if (scroll) {
  170.  
  171.             /* Scroll list down */
  172.             getyx (dialog, cur_y, cur_x);
  173.             if (list_height > 1) {
  174.                 /* De-highlight current first item */
  175.                 print_item (list, items[scroll * 3],
  176.                       items[scroll * 3 + 1], status[scroll],
  177.                     0, FALSE);
  178.                 scrollok (list, TRUE);
  179.                 wscrl (list, -1);
  180.                 scrollok (list, FALSE);
  181.             }
  182.             scroll--;
  183.             print_item (list, items[scroll * 3],
  184.                     items[scroll * 3 + 1], status[scroll],
  185.                     0, TRUE);
  186.             wnoutrefresh (list);
  187.  
  188.             /* print the up/down arrows */
  189.             wmove (dialog, box_y, box_x + check_x + 5);
  190.             wattrset (dialog, scroll ? uarrow_attr : menubox_attr);
  191.             waddch (dialog, scroll ? ACS_UARROW : ACS_HLINE);
  192.             wmove (dialog, box_y, box_x + check_x + 6);
  193.             waddch (dialog, scroll ? '(' : ACS_HLINE);
  194.             wmove (dialog, box_y, box_x + check_x + 7);
  195.             waddch (dialog, scroll ? '-' : ACS_HLINE);
  196.             wmove (dialog, box_y, box_x + check_x + 8);
  197.             waddch (dialog, scroll ? ')' : ACS_HLINE);
  198.             wattrset (dialog, darrow_attr);
  199.             wmove (dialog, box_y + list_height + 1,
  200.                    box_x + check_x + 5);
  201.             waddch (dialog, ACS_DARROW);
  202.             wmove (dialog, box_y + list_height + 1,
  203.                    box_x + check_x + 6);
  204.             waddch (dialog, '(');
  205.             wmove (dialog, box_y + list_height + 1,
  206.                    box_x + check_x + 7);
  207.             waddch (dialog, '+');
  208.             wmove (dialog, box_y + list_height + 1,
  209.                    box_x + check_x + 8);
  210.             waddch (dialog, ')');
  211.             wmove (dialog, cur_y, cur_x);
  212.             wrefresh (dialog);
  213.             }
  214.             continue;    /* wait for another key press */
  215.         } else
  216.             i = choice - 1;
  217.         } else if (key == KEY_DOWN || key == '+') {
  218.         if (choice == max_choice - 1) {
  219.             if (scroll + choice < item_no - 1) {
  220.             /* Scroll list up */
  221.             getyx (dialog, cur_y, cur_x);
  222.             if (list_height > 1) {
  223.                 /* De-highlight current last item */
  224.                 print_item (list, items[(scroll + max_choice - 1)
  225.                  * 3], items[(scroll + max_choice - 1) * 3 + 1],
  226.                     status[scroll + max_choice - 1],
  227.                     max_choice - 1, FALSE);
  228.                 scrollok (list, TRUE);
  229.                 scroll (list);
  230.                 scrollok (list, FALSE);
  231.             }
  232.             scroll++;
  233.             print_item (list, items[(scroll + max_choice - 1) * 3],
  234.                     items[(scroll + max_choice - 1) * 3 + 1],
  235.                     status[scroll + max_choice - 1],
  236.                     max_choice - 1, TRUE);
  237.             wnoutrefresh (list);
  238.  
  239.             /* print the up/down arrows */
  240.             wattrset (dialog, uarrow_attr);
  241.             wmove (dialog, box_y, box_x + check_x + 5);
  242.             waddch (dialog, ACS_UARROW);
  243.             wmove (dialog, box_y, box_x + check_x + 6);
  244.             waddstr (dialog, "(-)");
  245.             wmove (dialog, box_y + list_height + 1,
  246.                    box_x + check_x + 5);
  247.             wattrset (dialog, scroll + choice < item_no - 1 ?
  248.                   darrow_attr : menubox_border_attr);
  249.             waddch (dialog, scroll + choice < item_no - 1 ?
  250.                 ACS_DARROW : ACS_HLINE);
  251.             wmove (dialog, box_y + list_height + 1,
  252.                    box_x + check_x + 6);
  253.             waddch (dialog, scroll + choice < item_no - 1 ?
  254.                 '(' : ACS_HLINE);
  255.             wmove (dialog, box_y + list_height + 1,
  256.                    box_x + check_x + 7);
  257.             waddch (dialog, scroll + choice < item_no - 1 ?
  258.                 '+' : ACS_HLINE);
  259.             wmove (dialog, box_y + list_height + 1,
  260.                    box_x + check_x + 8);
  261.             waddch (dialog, scroll + choice < item_no - 1 ?
  262.                 ')' : ACS_HLINE);
  263.             wmove (dialog, cur_y, cur_x);
  264.             wrefresh (dialog);
  265.             }
  266.             continue;    /* wait for another key press */
  267.         } else
  268.             i = choice + 1;
  269.         } else if (key == ' ') {    /* Toggle item status */
  270.         if (status[scroll + choice])
  271.             continue;
  272.         for (i = 0; i < item_no; i++)
  273.             status[i] = 0;
  274.         status[scroll + choice] = 1;
  275.         getyx (dialog, cur_y, cur_x);
  276.         for (i = 0; i < max_choice; i++)
  277.             print_item (list, items[(scroll + i) * 3],
  278.                 items[(scroll + i) * 3 + 1], status[scroll + i],
  279.                 i, i == choice);
  280.         wnoutrefresh (list);
  281.         wmove (dialog, cur_y, cur_x);
  282.         wrefresh (dialog);
  283.         continue;    /* wait for another key press */
  284.         }
  285.         if (i == choice)
  286.         continue;
  287.         /* De-highlight current item */
  288.         getyx (dialog, cur_y, cur_x);
  289.         print_item (list, items[(scroll + choice) * 3],
  290.             items[(scroll + choice) * 3 + 1],
  291.             status[scroll + choice], choice, FALSE);
  292.         /* Highlight new item */
  293.         choice = i;
  294.         print_item (list, items[(scroll + choice) * 3],
  295.             items[(scroll + choice) * 3 + 1],
  296.             status[scroll + choice], choice, TRUE);
  297.         wnoutrefresh (list);
  298.         wmove (dialog, cur_y, cur_x);
  299.         wrefresh (dialog);
  300.         continue;        /* wait for another key press */
  301.     }
  302.     switch (key) {
  303.     case 'O':
  304.     case 'o':
  305.         delwin (dialog);
  306.         for (i = 0; i < item_no; i++)
  307.         if (status[i])
  308.             fprintf (stderr, "%s", items[i * 3]);
  309.         free (status);
  310.         return 0;
  311.     case 'C':
  312.     case 'c':
  313.         delwin (dialog);
  314.         free (status);
  315.         return 1;
  316.     case TAB:
  317.     case KEY_LEFT:
  318.     case KEY_RIGHT:
  319.         if (!button) {
  320.         button = 1;
  321.         print_button (dialog, "  OK  ", y, x, FALSE);
  322.         print_button (dialog, "Cancel", y, x + 14,
  323.                   TRUE);
  324.         } else {
  325.         button = 0;
  326.         print_button (dialog, "Cancel", y, x + 14,
  327.                   FALSE);
  328.         print_button (dialog, "  OK  ", y, x, TRUE);
  329.         }
  330.         wrefresh (dialog);
  331.         break;
  332.     case ' ':
  333.     case '\n':
  334.         delwin (dialog);
  335.         if (!button)
  336.         for (i = 0; i < item_no; i++)
  337.             if (status[i])
  338.             fprintf (stderr, items[i * 3]);
  339.         free (status);
  340.         return button;
  341.     case ESC:
  342.         break;
  343.     }
  344.     }
  345.  
  346.     delwin (dialog);
  347.     free (status);
  348.     return -1;            /* ESC pressed */
  349. }
  350.